using System;
using System.Runtime.Serialization;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Pegasus.UnitTests.Runtime.Serialization.Formatters.Xml.XmlFormatter2Tests
{
	/// <summary>
	/// This is a test class for Pegasus.Runtime.Serialization.Formatters.Xml.XmlFormatter2
	/// and will check class serialization using the Serializable attribute.
	///</summary>
	[TestClass]
	public class XmlFormatter2SerializableAttributeTests
	{
		// Local Instance Values
		private TestContext m_testContextInstance;

		/// <summary>
		/// Initializes a new instance of the <see cref="T:XmlFormatter2SerializableAttributeTests"/> class.
		/// </summary>
		public XmlFormatter2SerializableAttributeTests()
		{
		}

		/// <summary>
		/// Gets or sets the test context which provides information about and 
		/// functionality for the current test run.
		/// </summary>
		/// <value>The test context.</value>
		public TestContext TestContext
		{
			get
			{
				return m_testContextInstance;
			}
			set
			{
				m_testContextInstance = value;
			}
		}

		/// <summary>
		/// Test the Serialize method (basic object)
		/// </summary>
		[TestMethod]
		public void SerializeObjectTest1()
		{
			// Build the object to serialize 
			SerializationRoot startObj = new SerializationRoot();
			startObj.Name = XmlFormatter2Helper.StringTestValue;
			startObj.Description = XmlFormatter2Helper.StringTestValue;

			// Send the object through the serializtion and deserializtion process
			SerializationRoot finishedObj = (SerializationRoot) XmlFormatter2Helper.SerializeDeserialize( startObj );

			// Check test results
			Assert.IsNotNull( finishedObj, "Deserialize return null object" );
			Assert.AreEqual( finishedObj.Name, XmlFormatter2Helper.StringTestValue, "Name value is not right" );
			Assert.AreEqual( finishedObj.Description, XmlFormatter2Helper.StringTestValue, "Description value is not right" );
		}

		/// <summary>
		/// Test the Serialize method (derived object)
		/// </summary>
		[TestMethod]
		public void SerializeObjectTest2()
		{
			// Build the object to serialize 
			SerializationChild startObj = new SerializationChild();
			startObj.Name = XmlFormatter2Helper.StringTestValue;
			startObj.Description = XmlFormatter2Helper.StringTestValue;
			startObj.Count = XmlFormatter2Helper.IntTestValue;
			startObj.NonserializeCount = XmlFormatter2Helper.IntTestValue;

			// Send the object through the serializtion and deserializtion process
			SerializationChild finishedObj = (SerializationChild) XmlFormatter2Helper.SerializeDeserialize( startObj );

			// Check test results
			Assert.IsNotNull( finishedObj, "Deserialize return null object" );
			Assert.AreEqual( finishedObj.Name, XmlFormatter2Helper.StringTestValue, "Name value is not right" );
			Assert.AreEqual( finishedObj.Description, XmlFormatter2Helper.StringTestValue, "Description value is not right" );
			Assert.IsNull( finishedObj.OtherObject, "OtherObject value is not right" );
			Assert.AreEqual( finishedObj.Count, XmlFormatter2Helper.IntTestValue, "Count value is not right" );
			Assert.AreNotEqual( finishedObj.NonserializeCount, XmlFormatter2Helper.IntTestValue, "NonCount value is not right" );
		}

		/// <summary>
		/// Test the Serialize method (nonserialized derived object)
		/// </summary>
		[TestMethod]
		[ExpectedException( typeof( SerializationException ), "Expected SerializeException" )]
		public void SerializeObjectTest3()
		{
			// Build the object to serialize 
			NonserializationChild startObj = new NonserializationChild();
			startObj.Name = XmlFormatter2Helper.StringTestValue;
			startObj.Description = XmlFormatter2Helper.StringTestValue;
			startObj.Count = XmlFormatter2Helper.IntTestValue;

			// Send the object through the serializtion and deserializtion process
			NonserializationChild finishedObj = (NonserializationChild) XmlFormatter2Helper.SerializeDeserialize( startObj );

			// Check test results
			// Should throw a serialize exception
		}

		/// <summary>
		/// Test the Serialize method (embedded objects)
		/// </summary>
		[TestMethod]
		public void SerializeObjectTest4()
		{
			// Build the object to serialize 
			SerializationChild startObj = new SerializationChild();
			startObj.Name = XmlFormatter2Helper.StringTestValue;
			startObj.Description = XmlFormatter2Helper.StringTestValue;
			startObj.Count = XmlFormatter2Helper.IntTestValue;
			startObj.NonserializeCount = XmlFormatter2Helper.IntTestValue;

			// Embed a sub-object of proper type
			startObj.OtherObject = new SerializationRoot();
			startObj.OtherObject.Name = XmlFormatter2Helper.StringTestValue;
			startObj.OtherObject.Description = XmlFormatter2Helper.StringTestValue;

			// Send the object through the serializtion and deserializtion process
			SerializationChild finishedObj = (SerializationChild) XmlFormatter2Helper.SerializeDeserialize( startObj );

			// Check test results
			Assert.IsNotNull( finishedObj, "Deserialize return null object" );
			Assert.AreEqual( finishedObj.Name, XmlFormatter2Helper.StringTestValue, "Name value is not right" );
			Assert.AreEqual( finishedObj.Description, XmlFormatter2Helper.StringTestValue, "Description value is not right" );
			Assert.AreEqual( finishedObj.Count, XmlFormatter2Helper.IntTestValue, "Count value is not right" );
			Assert.AreNotEqual( finishedObj.NonserializeCount, XmlFormatter2Helper.IntTestValue, "NonCount value is not right" );

			Assert.IsNotNull( finishedObj.OtherObject, "OtherObject value is not right" );
			Assert.AreEqual( finishedObj.OtherObject.Name, XmlFormatter2Helper.StringTestValue, "OtherObject Name value is not right" );
			Assert.AreEqual( finishedObj.OtherObject.Description, XmlFormatter2Helper.StringTestValue, "OtherObject Description value is not right" );
		}


		/// <summary>
		/// Test the Serialize method (embedded derived objects)
		/// </summary>
		[TestMethod]
		public void SerializeObjectTest5()
		{
			// Build the object to serialize 
			SerializationChild startObj = new SerializationChild();
			startObj.Name = XmlFormatter2Helper.StringTestValue;
			startObj.Description = XmlFormatter2Helper.StringTestValue;
			startObj.Count = XmlFormatter2Helper.IntTestValue;
			startObj.NonserializeCount = XmlFormatter2Helper.IntTestValue;

			// Embed a sub-object of proper type
			SerializationChild embeddedObj = new SerializationChild();
			embeddedObj.Name = XmlFormatter2Helper.StringTestValue;
			embeddedObj.Description = XmlFormatter2Helper.StringTestValue;
			embeddedObj.Count = XmlFormatter2Helper.IntTestValue;
			embeddedObj.NonserializeCount = XmlFormatter2Helper.IntTestValue;

			startObj.OtherObject = embeddedObj;

			// Send the object through the serializtion and deserializtion process
			SerializationChild finishedObj = (SerializationChild) XmlFormatter2Helper.SerializeDeserialize( startObj );

			// Check test results
			Assert.IsNotNull( finishedObj, "Deserialize return null object" );
			Assert.AreEqual( finishedObj.Name, XmlFormatter2Helper.StringTestValue, "Name value is not right" );
			Assert.AreEqual( finishedObj.Description, XmlFormatter2Helper.StringTestValue, "Description value is not right" );
			Assert.AreEqual( finishedObj.Count, XmlFormatter2Helper.IntTestValue, "Count value is not right" );
			Assert.AreNotEqual( finishedObj.NonserializeCount, XmlFormatter2Helper.IntTestValue, "NonCount value is not right" );

			Assert.IsNotNull( finishedObj.OtherObject, "OtherObject value is not right" );
			Assert.IsInstanceOfType( finishedObj.OtherObject, typeof( SerializationChild ), "OtherObject has wrong type" );

			SerializationChild finishedEmbeddedObj = (SerializationChild) finishedObj.OtherObject;

			Assert.AreEqual( finishedEmbeddedObj.Name, XmlFormatter2Helper.StringTestValue, "Name value is not right" );
			Assert.AreEqual( finishedEmbeddedObj.Description, XmlFormatter2Helper.StringTestValue, "Description value is not right" );
			Assert.AreEqual( finishedEmbeddedObj.Count, XmlFormatter2Helper.IntTestValue, "Count value is not right" );
			Assert.AreNotEqual( finishedEmbeddedObj.NonserializeCount, XmlFormatter2Helper.IntTestValue, "NonCount value is not right" );
		}
	}
}
